既存のロググループ用の「CloudWatch Logsの異常検出を設定するCloudFormationテンプレート」を作成するスクリプトを作ってみた #AWSreInvent
Amazon CloudWatch Logsの異常検出ができるようになりました。 とはいえ、既存のロググループがたくさんあるとき、ひとつひとつ設定するのは大変です。 というわけで、「既存のロググループの一覧を取得して、CloudWatch Logsの異常検出を設定するCloudFormationテンプレート」を作成するスクリプトを作ってみました。
おすすめの方
- CloudWatch Logsの異常検出をCloudFormationで設定したい方
- CloudWatch Logsの異常検出を既存のロググループになるべく簡単に適用したい方
今回のお試し対象
今回は、ロググループのprefixが「/aws-glue」である3つのロググループで試してみます。
「CloudWatch Logsの異常検出を設定するCloudFormationテンプレート」を作成するスクリプト
次のパラメータをいい感じにすると便利です。(どちらかひとつだけを指定できます)
- logGroupNamePrefix
- logGroupNamePattern
なお事前に次のライブラリをインストールしておきます。
# pip install pyyaml # pip install boto3 import yaml import boto3 logs = boto3.client("logs") base = { "AWSTemplateFormatVersion": "2010-09-09", "Description": "CloudWatch Logs Anomaly Detector Sample made by Python", "Resources": {}, } RESOURCE_NAME_SUFFIX = "LogAnomalyDetector" RESOURCE_NAME_MAX_LENGTH = 255 OUTPUT_FILE_NAME = "cloudwatch_log_anomaly_detector.yaml" def main(): log_groups = get_log_groups() for log_group in log_groups: resource = make_cloudwatch_logs_anomaly_detector(log_group) base["Resources"].update(resource) with open(OUTPUT_FILE_NAME, "w") as f: yaml.dump(base, f, default_flow_style=False, sort_keys=False) def get_log_groups(): log_groups = [] options = { "logGroupNamePrefix": "/aws-glue", # "logGroupNamePrefix": "/aws/lambda", # "logGroupNamePattern": ".*", "logGroupClass": "STANDARD", # "limit": 5, } while True: resp = logs.describe_log_groups(**options) log_groups += resp["logGroups"] if "nextToken" not in resp: break options["nextToken"] = resp["nextToken"] return log_groups def make_cloudwatch_logs_anomaly_detector(log_group: dict[str, str]): log_group_name = log_group["logGroupName"] log_group_arn = log_group["arn"] return { convert_resource_name(log_group_name): { "Type": "AWS::Logs::LogAnomalyDetector", "Properties": { "DetectorName": log_group_name, "AnomalyVisibilityTime": 21, "EvaluationFrequency": "FIFTEEN_MIN", "LogGroupArnList": [convert_arn(log_group_arn)], }, } } def convert_resource_name(log_group_name: str): # https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html resource_name = ( log_group_name.replace("_", "") .replace("-", "") .replace("/", "") .replace(".", "") .replace("#", "") ) return resource_name[: RESOURCE_NAME_MAX_LENGTH - len(RESOURCE_NAME_SUFFIX) - 1] + RESOURCE_NAME_SUFFIX def convert_arn(arn: str) -> str: # 末尾の「:*」を削る return arn[:-2] if __name__ == "__main__": main()
スクリプトを実行して、CloudFormationテンプレートを作成する
python app.py
作成されたCloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09' Description: CloudWatch Logs Anomaly Detector Sample made by Python Resources: awsgluecrawlersLogAnomalyDetector: Type: AWS::Logs::LogAnomalyDetector Properties: DetectorName: /aws-glue/crawlers AnomalyVisibilityTime: 21 EvaluationFrequency: FIFTEEN_MIN LogGroupArnList: - arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws-glue/crawlers awsgluejobserrorLogAnomalyDetector: Type: AWS::Logs::LogAnomalyDetector Properties: DetectorName: /aws-glue/jobs/error AnomalyVisibilityTime: 21 EvaluationFrequency: FIFTEEN_MIN LogGroupArnList: - arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws-glue/jobs/error awsgluejobsoutputLogAnomalyDetector: Type: AWS::Logs::LogAnomalyDetector Properties: DetectorName: /aws-glue/jobs/output AnomalyVisibilityTime: 21 EvaluationFrequency: FIFTEEN_MIN LogGroupArnList: - arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws-glue/jobs/output
ロググループのARNが複数指定できるように見えますが、ひとつのみ指定できます。 そのため、ロググループの数だけリソースを作成しています。
The ARN of the log group that is associated with this anomaly detector. You can specify only one log group ARN.
デプロイする
aws cloudformation deploy \ --template-file cloudwatch_log_anomaly_detector.yaml \ --stack-name CloudWatch-Logs-Anomaly-Detector-glue-Sample-Stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
CloudWatch Logsの様子を見る
しっかりデプロイされていました。
AWS CLIで異常ディテクターの一覧を取得する
今回デプロイした3つの異常ディテクターがあります。 他の2つは以前にデプロイした異常ディテクターです。
aws logs list-log-anomaly-detectors \ --query 'anomalyDetectors[*].detectorName' [ "lambda-2-log-anomaly-detector-sample", "/aws-glue/jobs/output", "/aws-glue/jobs/error", "/aws-glue/crawlers", "lambda-1-log-anomaly-detector-sample" ]